﻿//    CMake Classifier:  Syntax coloring and highlighting Visual Studio Extension
//    Copyright (C) 2011 Steven Velez
//
//    This file is part of CMake Classifier
//
//    CMake Classifier is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Lesser General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;

namespace CMakeClassifier
{
    #region Content Type Setup
    /// <summary>
    /// Set up content types.
    /// </summary>
    /// <remarks>
    /// This class provides context for setting up some exports that
    /// are necessary for configuring the CMake content type and associating that
    /// to the four common cmake file "extensions":
    /// 
    ///     .cmake
    ///     .ctest
    ///     .in
    ///     .txt
    ///     
    /// Of course, not all ".txt" files are cmake files, but "CMakeLists.txt"
    /// is not usable as an extension for association to a content type.  "in" has
    /// similar issues, so this will be handled further when registereing the classifer
    /// </remarks>
    internal class ContentTypeInfo
    {
        // Never mind the warning of these variables not being used... they ARE used 
        // by the MEF.  I guess the compiler doesn't realize that.
#pragma warning disable 649
        [Export]
        [Name("CMake")]
        [BaseDefinition("code")]
        internal static ContentTypeDefinition CMakeContentTypeDefiniton;

        [Export]
        [FileExtension(".cmake")]
        [ContentType("CMake")]
        internal static FileExtensionToContentTypeDefinition CMakeModuleExtensionToContentTypeDefinition;

        [Export]
        [FileExtension(".txt")]
        [ContentType("CMake")]
        internal static FileExtensionToContentTypeDefinition CMakeListFileExtensionToContentTypeDefinition;

        [Export]
        [FileExtension(".in")]
        [ContentType("CMake")]
        internal static FileExtensionToContentTypeDefinition CMakeInputModuleExtensionToContentTypeDefinition;

        [Export]
        [FileExtension(".ctest")]
        [ContentType("CMake")]
        internal static FileExtensionToContentTypeDefinition CMakeTestModuleExtensionToContentTypeDefinition;
#pragma warning restore 649
    }
    #endregion

    #region Provider definition
    /// <summary>
    /// This class causes a classifier to be added to the set of classifiers. Since 
    /// the content type is set to "cmake", this classifier applies to all cmake files.
    /// This includes those ending in ".cmake" and ".txt" (though using the .txt extension
    /// may be considered a bit overly aggressive)
    /// </summary>
    [Export(typeof(IClassifierProvider))]
    [ContentType("CMake")]
    internal class CMakeClassifierProvider : IClassifierProvider
    {
        /// <summary>
        /// Import the classification registry to be used for getting a reference
        /// to the custom classification type later.
        /// </summary>
        [Import]
        internal IClassificationTypeRegistryService ClassificationRegistry = null; // Set via MEF

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            return buffer.Properties.GetOrCreateSingletonProperty<CMakeClassifier>(delegate { return new CMakeClassifier(ClassificationRegistry, buffer); });
        }
    }
    #endregion //provider def

}
